package org.jflame.commons.util;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符编码工具类.
 * 
 * @see java.nio.charset.StandardCharsets
 * @see org.apache.commons.lang3.CharUtils
 * @author charles.zhang
 */
public abstract class CharsetHelper {

    /**
     * gbk18030编码
     */
    public static final Charset GBK_18030 = Charset.forName("GB18030");

    /**
     * 使用utf-8解码字符串
     * 
     * @param string
     * @return
     */
    public static byte[] getUtf8Bytes(String string) {
        return string.getBytes(StandardCharsets.UTF_8);
    }

    /**
     * 将byte[]使用utf-8编码为字符串
     * 
     * @param bytes byte[]
     * @return
     */
    public static String getUtf8String(byte[] bytes) {
        return bytes == null ? null : new String(bytes, StandardCharsets.UTF_8);
    }

    /**
     * 使用指定编码重新编码字符串
     * 
     * @param str 字符串
     * @param decodeCharset 原字符编码
     * @param encodeCharset 新字符编码
     * @return
     */
    public static String reEncode(final String str, Charset decodeCharset, Charset encodeCharset) {
        return new String(str.getBytes(decodeCharset), encodeCharset);
    }

    /**
     * 解码GBK汉字编码为ISO88591
     * 
     * @param str
     * @return
     */
    public static String reEncodeGBK(final String str) {
        return reEncode(str, GBK_18030, StandardCharsets.ISO_8859_1);
    }

    /**
     * 字符串中的unicode解码为普通字符
     * 
     * @param unicodeStr
     * @return
     */
    public static String decodeUnicode(String unicodeStr) {
        int length = unicodeStr.length();
        int count = 0,index;
        // 正则匹配条件，可匹配“\\u”1到4位，一般是4位可直接使用 String regex = "\\\\u[a-f0-9A-F]{4}";
        Pattern pattern = Pattern.compile("\\\\u[a-f0-9A-F]{1,4}");
        Matcher matcher = pattern.matcher(unicodeStr);
        StringBuilder sb = new StringBuilder(length);
        String tmpUnicodeChar;
        while (matcher.find()) {
            tmpUnicodeChar = matcher.group();// 原本的Unicode字符
            index = matcher.start();
            sb.append(unicodeStr.substring(count, index));// 添加前面不是unicode的字符
            sb.append((char) Integer.parseInt(tmpUnicodeChar.substring(2), 16));// 转单个unicode字符
            count = index + tmpUnicodeChar.length();// 统计下标移动的位置
        }
        sb.append(unicodeStr.substring(count, length));// 添加末尾不是Unicode的字符
        return sb.toString();
    }

    /**
     * unicode字符串转为普通字符串.<strong>整个字符串都是unicode字符</strong>
     * 
     * @param unicodeStr unicode字符串
     * @return
     */
    public static String fromUnicode(String unicodeStr) {
        String[] hex = unicodeStr.split("\\\\u");
        char[] arr = new char[hex.length - 1];// 第一个是空, 如:[, 61, 64, 62, 4e2d]
        for (int i = 1; i < hex.length; i++) {
            arr[i - 1] = (char) Integer.parseInt(hex[i], 16);
        }
        return new String(arr);
    }

    /**
     * 普通字符串转为unicode字符串
     * 
     * @param string
     * @return
     */
    public static String toUnicode(final String string) {
        int len = string.length();
        StringBuilder unicode = new StringBuilder(len * 4);
        for (int i = 0; i < len; i++) {
            unicode.append("\\u")
                    .append(Integer.toHexString(string.charAt(i)));
        }
        return unicode.toString();
    }

}
